/*******************************************************************/
/*                                                                 */
/*  NAME    = send_pcap_thread.cpp                                                   */
/*  NOTE    =                                                      */
/*  DATE    = 2014/12/11 by yinghl                                    */
/*******************************************************************/

#include "send_pcap_thread.h"
#include "TestCaseManager.h"
#include "TestCase.h"
#include "send_pcap.h"

#include <iostream>

using namespace std;

/*******************************************************************************
*  FUNC     :   构造函数初始化一些成员变量
*  ARGS     :   caseMnger (class TestCaseManager, 管理所有case)
                mutex (多线程互斥锁，防止同时操作)
                conditions (class CaseConditions, 需要测试的条件)
                fps (发包频率)
                libnet (libnet句柄)
*  RTN      :
*  NOTE     :
*******************************************************************************/
SendPcapThread::SendPcapThread(TestCaseManager &caseMnger, pthread_mutex_t &mutex,
        const CaseConditions &conditions, uint32_t fps, libnet_t *libnet)
    :caseMnger_(caseMnger), mutex_(mutex), conditions_(conditions),
     fps_(fps), libnetHandle_(libnet), changePort_(0)
{
}

/********************************************************************************
*  FUNC     :   析构函数
*  ARGS     :
*  RTN      :
*  NOTE     :
*******************************************************************************/
SendPcapThread::~SendPcapThread()
{
}

/********************************************************************************
*  FUNC     :   线程处理函数
*  ARGS     :
*  RTN      :
*  NOTE     :   获取未发送的pcap文件并发送
*******************************************************************************/
void SendPcapThread::DoProcess()
{
    while(1)
    {
        string pcap = getNotSendPcap();
        if(pcap.length() != 0)
        {
            cout << "send " << pcap << endl;
            //发送pcap数据
            SendPcap sendPcap(pcap, fps_, libnetHandle_, changePortCmpData_, changePort_);
            sendPcap.doSend();
        }
        else
        {
            break;
        }
    }
}

/********************************************************************************
*  FUNC     :   获取未发送的pcap文件
*  ARGS     :
*  RTN      :
*  NOTE     :
*******************************************************************************/
string SendPcapThread::getNotSendPcap()
{
    string pcap;
    pthread_mutex_lock(&mutex_);
    uint32_t caseNum = caseMnger_.GetTestCaseNum();
    for(uint32_t i = 0; i < caseNum; i++)
    {
        TestCase &tmpCase = caseMnger_.GetTestCase(i);
        if(tmpCase.GetPassed()) continue;

        if(!tmpCase.DoTestCase(conditions_)) continue;

        pcap = tmpCase.GetPcap();
        tmpCase.SetPassed(true);

        break;
    }
    pthread_mutex_unlock(&mutex_);

    return pcap;
}

/********************************************************************************
*  FUNC     :   设置更改端口号的条件及更改的端口号
*  ARGS     :
                portCmpData (更改端口号的条件)
                changePort (更改的端口号)
*  RTN      :
*  NOTE     :
*******************************************************************************/
void SendPcapThread::setChangePortInfo(const string &portCmpData, int changePort)
{
    changePortCmpData_ = portCmpData;
    changePort_ = changePort;
}
